<%!

  Copyright (c) Facebook, Inc. and its affiliates.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

%><%#struct:fields%>
<%#field:cpp_ref?%>
<%#field:boxed_ref?%>
  template <typename..., typename T = <%field:cpp_storage_type%>>
  FOLLY_ERASE ::apache::thrift::optional_boxed_field_ref<const T&> <%field:cpp_name%>_ref() const& {
    return {this-><% > common/field_value%>};
  }

  template <typename..., typename T = <%field:cpp_storage_type%>>
  FOLLY_ERASE ::apache::thrift::optional_boxed_field_ref<const T&&> <%field:cpp_name%>_ref() const&& {
    return {std::move(this-><% > common/field_value%>)};
  }

  template <typename..., typename T = <%field:cpp_storage_type%>>
  FOLLY_ERASE ::apache::thrift::optional_boxed_field_ref<T&> <%field:cpp_name%>_ref() & {
    return {this-><% > common/field_value%>};
  }

  template <typename..., typename T = <%field:cpp_storage_type%>>
  FOLLY_ERASE ::apache::thrift::optional_boxed_field_ref<T&&> <%field:cpp_name%>_ref() && {
    return {std::move(this-><% > common/field_value%>)};
  }
<%/field:boxed_ref?%>
<%^field:boxed_ref?%>
  template <typename ..., typename T = <%field:cpp_storage_type%>>
  FOLLY_ERASE T& <%field:cpp_name%>_ref() & { return <% > common/field_value%>; }

  template <typename ..., typename T = <%field:cpp_storage_type%>>
  FOLLY_ERASE const T& <%field:cpp_name%>_ref() const& { return <% > common/field_value%>; }

  template <typename ..., typename T = <%field:cpp_storage_type%>>
  FOLLY_ERASE T&& <%field:cpp_name%>_ref() && { return std::move(<% > common/field_value%>); }

  template <typename ..., typename T = <%field:cpp_storage_type%>>
  FOLLY_ERASE const T&& <%field:cpp_name%>_ref() const&& { return std::move(<% > common/field_value%>); }
<%/field:boxed_ref?%>
<%/field:cpp_ref?%>
<%^field:cpp_ref?%>
<%#field:optional?%>

  template <typename..., typename T = <%field:cpp_storage_type%>>
  FOLLY_ERASE ::apache::thrift::optional_field_ref<const T&> <%field:cpp_name%>_ref() const& {
    return {this-><% > common/field_value%>, __isset.array_isset.at(folly::index_constant<<%field:isset_index%>>())};
  }

  template <typename..., typename T = <%field:cpp_storage_type%>>
  FOLLY_ERASE ::apache::thrift::optional_field_ref<const T&&> <%field:cpp_name%>_ref() const&& {
    return {std::move(this-><% > common/field_value%>), __isset.array_isset.at(folly::index_constant<<%field:isset_index%>>())};
  }

  template <typename..., typename T = <%field:cpp_storage_type%>>
  FOLLY_ERASE ::apache::thrift::optional_field_ref<T&> <%field:cpp_name%>_ref() & {
    return {this-><% > common/field_value%>, __isset.array_isset.at(folly::index_constant<<%field:isset_index%>>())};
  }

  template <typename..., typename T = <%field:cpp_storage_type%>>
  FOLLY_ERASE ::apache::thrift::optional_field_ref<T&&> <%field:cpp_name%>_ref() && {
    return {std::move(this-><% > common/field_value%>), __isset.array_isset.at(folly::index_constant<<%field:isset_index%>>())};
  }
<%/field:optional?%>
<%^field:optional?%>
<%#field:required?%>

  template <typename..., typename T = <%field:cpp_storage_type%>>
  FOLLY_ERASE ::apache::thrift::required_field_ref<const T&> <%field:cpp_name%>_ref() const& {
    return ::apache::thrift::required_field_ref<const T&>{this-><% > common/field_value%>};
  }

  template <typename..., typename T = <%field:cpp_storage_type%>>
  FOLLY_ERASE ::apache::thrift::required_field_ref<const T&&> <%field:cpp_name%>_ref() const&& {
    return ::apache::thrift::required_field_ref<const T&&>{std::move(this-><% > common/field_value%>)};
  }

  template <typename..., typename T = <%field:cpp_storage_type%>>
  FOLLY_ERASE ::apache::thrift::required_field_ref<T&> <%field:cpp_name%>_ref() & {
    return ::apache::thrift::required_field_ref<T&>{this-><% > common/field_value%>};
  }

  template <typename..., typename T = <%field:cpp_storage_type%>>
  FOLLY_ERASE ::apache::thrift::required_field_ref<T&&> <%field:cpp_name%>_ref() && {
    return ::apache::thrift::required_field_ref<T&&>{std::move(this-><% > common/field_value%>)};
  }
<%/field:required?%>
<%^field:required?%>

  template <typename..., typename T = <%field:cpp_storage_type%>>
  FOLLY_ERASE ::apache::thrift::field_ref<const T&> <%field:cpp_name%>_ref() const& {
    return {this-><% > common/field_value%>, __isset.array_isset.at(folly::index_constant<<%field:isset_index%>>())};
  }

  template <typename..., typename T = <%field:cpp_storage_type%>>
  FOLLY_ERASE ::apache::thrift::field_ref<const T&&> <%field:cpp_name%>_ref() const&& {
    return {std::move(this-><% > common/field_value%>), __isset.array_isset.at(folly::index_constant<<%field:isset_index%>>())};
  }

  template <typename..., typename T = <%field:cpp_storage_type%>>
  FOLLY_ERASE ::apache::thrift::field_ref<T&> <%field:cpp_name%>_ref() & {
    return {this-><% > common/field_value%>, __isset.array_isset.at(folly::index_constant<<%field:isset_index%>>())};
  }

  template <typename..., typename T = <%field:cpp_storage_type%>>
  FOLLY_ERASE ::apache::thrift::field_ref<T&&> <%field:cpp_name%>_ref() && {
    return {std::move(this-><% > common/field_value%>), __isset.array_isset.at(folly::index_constant<<%field:isset_index%>>())};
  }
<%/field:required?%><%/field:optional?%>
<%/field:cpp_ref?%><%/struct:fields%>
<%#struct:mixin_fields%>
  FOLLY_ERASE auto <%mixin:field_name%>_ref() &       { return <%mixin:name%>.<%mixin:field_name%>_ref();            }
  FOLLY_ERASE auto <%mixin:field_name%>_ref() const&  { return <%mixin:name%>.<%mixin:field_name%>_ref();            }
  FOLLY_ERASE auto <%mixin:field_name%>_ref() &&      { return std::move(<%mixin:name%>).<%mixin:field_name%>_ref(); }
  FOLLY_ERASE auto <%mixin:field_name%>_ref() const&& { return std::move(<%mixin:name%>).<%mixin:field_name%>_ref(); }
<%/struct:mixin_fields%>
